<?php

require_once dirname(__FILE__) . '/../../../Domain51UnitTest.config.php';
require_once 'Domain51/Service/Amazon/S3.php';

class Domain51_Service_Amazon_S3Test extends PHPUnit_Framework_TestCase
{
    public function testCanInstantiateViaFactory() 
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $this->assertTrue($s3 instanceof Domain51_Service_Amazon_S3);
    }
    
    public function _testThrowsExceptionWhenPeclHttpExtensionNotLoaded()
    { 
        if (extension_loaded('http')) {
            // Can't run unless extension is not loaded, skip, but still run
            // for documentation purposes.
            return;
        }
        
        try {
            $s3 = Solar::factory('Domain51_Service_Amazon_S3');
            $this->fail('Exception not thrown');
        } catch (Exception $e) {
            $this->assertSame(
                'ERR_EXTENSION_NOT_LOADED',
                $e->getMessage()
            );
        }
    }
    
    public function testCanInstantiateWithPeclConnection_typeConfig()
    {
        $s3 = Solar::factory(
            'Domain51_Service_Amazon_S3', 
            array('connection_type' => 'pecl')
        );
        
        $this->assertTrue($s3 instanceof Domain51_Service_Amazon_S3);
    }
    
    public function testCanInstantiateWithZendConnection_typeConfig()
    {
        $s3 = Solar::factory(
            'Domain51_Service_Amazon_S3', 
            array('connection_type' => 'zend')
        );
        
        $this->assertTrue($s3 instanceof Domain51_Service_Amazon_S3);
    }
    
    public function testCanInstantiateWithPearConnection_typeConfig()
    {
        $s3 = Solar::factory(
            'Domain51_Service_Amazon_S3', 
            array('connection_type' => 'pear')
        );
        
        $this->assertTrue($s3 instanceof Domain51_Service_Amazon_S3);
    }
    
    public function testThrowsExceptionWhenInstantiatedWithUnknownConnection_typeConfig()
    {
        try{
            $s3 = Solar::factory(
                'Domain51_Service_Amazon_S3', 
                array('connection_type' => 'unknown')
            );
            $this->fail('Exception not caught');
        } catch (Exception $e) {
            $this->assertSame('ERR_UNKNOWN_CONNECTION_TYPE', $e->getMessage());
        }
    }
    
    public function testServicePropertyHasCallableGetMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $service = $s3->service;
        $this->assertTrue(method_exists($service, 'get'));
        $this->assertTrue(is_callable(array($service, 'get')));
    }
    
    public function testBucketPropertyHasCallablePutMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $bucket = $s3->bucket;
        $this->assertTrue(method_exists($bucket, 'put'));
        $this->assertTrue(is_callable(array($bucket, 'put')));
    }
    
    public function testBucketPropertyHasCallableGetMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $bucket = $s3->bucket;
        $this->assertTrue(method_exists($bucket, 'get'));
        $this->assertTrue(is_callable(array($bucket, 'get')));
    }
    
    public function testBucketPropertyHasCallableDeleteMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $bucket = $s3->bucket;
        $this->assertTrue(method_exists($bucket, 'delete'));
        $this->assertTrue(is_callable(array($bucket, 'delete')));
    }
    
    public function testObjectPropertyHasCallablePutMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $object = $s3->object;
        $this->assertTrue(method_exists($object, 'put'));
        $this->assertTrue(is_callable(array($object, 'put')));
    }
    
    public function testObjectPropertyHasCallableGetMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $object = $s3->object;
        $this->assertTrue(method_exists($object, 'get'));
        $this->assertTrue(is_callable(array($object, 'get')));
    }
    
    public function testObjectPropertyHasCallableHeadMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $object = $s3->object;
        $this->assertTrue(method_exists($object, 'head'));
        $this->assertTrue(is_callable(array($object, 'head')));
    }
    
    public function testObjectPropertyHasCallableDeleteMethod()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $object = $s3->object;
        $this->assertTrue(method_exists($object, 'delete'));
        $this->assertTrue(is_callable(array($object, 'delete')));
    }
    
    public function testUnknownPropertyThrowsException()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        try {
            $s3->unknown;
            $this->fail('Exception not thrown');
        } catch (Exception $e) {
            $this->assertSame('ERR_UNKNOWN_PROPERTY', $e->getMessage());
        }
    }
    
    public function testCreateWithObjectParamReturnsValue_object() 
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $object = $s3->create('object');
        $this->assertTrue($object instanceof Domain51_Service_Amazon_S3_Value_Object);
    }
    
    public function testCreateWithBucketParamReturnsValue_bucket()
    {
        $this->markTestIncomplete('Need to implement');
        
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        $bucket = $s3->create('bucket');
        $this->assertTrue($bucket instanceof Domain51_Service_Amazon_S3_Value_Bucket);
    }
    
    public function testCreateWithUnknownParamThrowsException()
    {
        $s3 = Solar::factory('Domain51_Service_Amazon_S3');
        
        try {
            $s3->create('unknown');
            $this->fail('Exception not thrown');
        } catch (Exception $e) {
            $this->assertSame('ERR_CONTAINER_NOT_IMPLEMENTED', $e->getMessage());
        }
    }
}

?>